{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"http://hilpisch.com/tpq_logo.png\" alt=\"The Python Quants\" width=\"35%\" align=\"right\" border=\"0\"><br><br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Listed Volatility and Variance Derivatives\n",
    "\n",
    "**Wiley Finance (2017)**\n",
    "\n",
    "Dr. Yves J. Hilpisch | The Python Quants GmbH\n",
    "\n",
    "http://tpq.io | [@dyjh](http://twitter.com/dyjh) | http://books.tpq.io\n",
    "\n",
    "<img src=\"http://hilpisch.com/../images/lvvd_cover.png\" alt=\"Derivatives Analytics with Python\" width=\"30%\" align=\"left\" border=\"0\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DX Analytics &mdash; Square-Root Jump Diffusion "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Introduction "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similar to the previous chapter, this chapter again uses DX Analytics to model the VSTOXX index, but this time by the square-root jump diffusion (SRJD) process as introduced in chapter _Advanced Modeling of the VSTOXX Index_. The study this chapter implements is actually the same as in the previous one using the very same data set. However, the challenge is increased in that we require that multiple VSTOXX option maturities shall be calibrated simultaneously and over time."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Modeling the VSTOXX Options"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "DX Analytics provides a class for the deterministic shift square-root jump diffusion model. It is called ``dx.square_root_jump_diffusion()``. Although the calibration we are implementing in this chapter is more or less the same as in the previous one, we need to nevertheless adjust the code in many places significantly. Therefore, we are stepping through the single elements again in what follows. All the code used in this chapter is found in the Python script ``dx_srjd_calibration.py`` (see the appendix for the complete scripts)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The beginning of the script is rather similar to the one implementing the calibration of the square-root diffusion model. A major difference is that we need three additional parameters ``lambda``, ``mu`` and ``delta``. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!sed -n 10,59p scripts/dx_srjd_calibration.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The function `srjd_get_option_selection()` selects the options used for the calibration. In the current case, we can choose multiple option maturities to be included."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append('scripts/')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import dx_srjd_calibration as dxsrjd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dxsrjd.srjd_get_option_selection??"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The calibration of the SRJD model consists of two steps:\n",
    "\n",
    "* **term structure calibration**: using the futures prices at a given pricing date, this step calibrates the forward rates of the model\n",
    "* **option quote calibration**: using market quotes of traded options, this step calibrates the model parameters to optimally reflect the market quotes\n",
    "\n",
    "Two functions are used to implement the first step. The function `srd_forward_error()` calculates the mean-squared error (MSE) for the futures term structure given a set of model parameters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dxsrjd.srd_forward_error??"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The second function is called `generate_shift_base()` and calculates the single deterministic shift values to match the futures term structure perfectly &mdash; after the minimization of the term structure MSE. Note that the perfect shift gets lost again later on when the SRD parameters get updated during the calibration to the option quotes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dxsrjd.generate_shift_base??"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As in the SRD calibration case, the function `srjd_get_option_models()` creates the valuation models for all selected options."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dxsrjd.srjd_get_option_models??"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Calibration of the VSTOXX Model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The function `srjd_calculate_model_values()` only differs from the SRD case in that three more parameters need to be taken care of."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dxsrjd.srjd_calculate_model_values??"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The same holds true for the function `srjd_mean_squared_error()` which now also penalizes certain parameter ranges for the additional parameters of the SRJD model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dxsrjd.srjd_mean_squared_error??"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The function `srjd_get_parameter_series()` implementing the calibration routines then takes on the  form:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dxsrjd.srjd_get_parameter_series??"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, the function ``srjd_plot_model_fit()`` plots the results for the last pricing date of the calibration procedure and compares the model values to the market quotes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dxsrjd.srjd_plot_model_fit??"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The final step is to start the calibration, collect the calibration results and to plot them. Remember that the maturities in this case are selected in the function `srjd_get_option_selection()`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dxsrjd.srjd_get_option_selection??"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Calibration Results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This section presents calibration results four three different calibration runs. The first run implements a calibration to a single, the second one to two maturities simultaneously while the third run does it for five maturities of the VSTOXX options. The final run shows the effects of not using penalties for deviations from previous optimal parameters which in general is used to get more smooth parameter time series."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Calibration to 1 Maturity"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we calibrate the SRJD model to a single maturity, 18. April 2014. The calibration takes place for all trading days in the first quarter of 2014. The following figure shows the time series data for the parameters of the square-root jump diffusion over time and the resulting MSE values. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_1.png\" width=\"75%\">\n",
    "\n",
    "<p style=\"font-family: monospace;\">Square-root jump diffusion parameters and MSE values from the calibration to two maturities."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The MSE values are all quite low in general with a mean of about 0.1 and one outlier as the following figure illustrates."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_1_hist.png\" width=\"75%\">\n",
    "\n",
    "<p style=\"font-family: monospace;\">Histogram of MSE values for SRJD calibration to two maturities."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following figure shows the calibration results for the last pricing date, i.e. on 31. March 2014."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_1_fit.png\" width=\"75%\">\n",
    "   \n",
    "<p style=\"font-family: monospace;\">Model values from the SRJD calibration vs. market quotes as well as pricing errors (bars) on 31. April 2014 (one maturity)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Calibration to 2 Maturities"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us have a look at the results for the calibration to two maturities where the VSTOXX futures term structure comes into play. The following figure shows the parameter time series data for this case. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_2.png\" width=\"75%\">\n",
    "   \n",
    "Square-root jump diffusion parameters and MSE values from the calibration to five maturities."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this case, the resulting MSE values are even a bit lower on average with a mean of about 0.05 as seen inthe follwing figure."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_2_hist.png\" width=\"75%\">   \n",
    "   \n",
    "<p style=\"font-family: monospace;\">Histogram of MSE values for SRJD calibration to five maturities."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following figure shows the calibration results for the last pricing date, i.e. on 31. March 2014."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_2_fit.png\" width=\"75%\"> \n",
    "\n",
    "<p style=\"font-family: monospace;\"> Model values from the SRJD calibration vs. market quotes as well as pricing errors (bars) on 31. April 2014 (two maturities)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Calibration to 5 Maturities"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, let us have a look at the calibration to five maturities simultaneously. This is the largest number of maturities for which there is data over the whole time range from January to March 2014. The following figure shows the results for the model parameters and the MSE values. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_5.png\" width=\"75%\">   \n",
    "\n",
    "<p style=\"font-family: monospace;\">Square-root jump diffusion parameters and MSE values from the calibration to five maturities."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The resulting MSE values are a again a bit lower on average. The mean MSE value is about 0.035 (see the following figure)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_5_hist.png\" width=\"75%\">   \n",
    "   \n",
    "<p style=\"font-family: monospace;\">Histogram of MSE values for SRJD calibration to five maturities."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The final plot (see the following figure) again shows the calibration results at the last pricing date, 31. March 2014. Given that the calibration includes options with different moneyness levels over five different maturity months, the performance of the SRJD model is satisfactory. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_5_fit.png\" width=\"75%\">   \n",
    "\n",
    "<p style=\"font-family: monospace;\">Model values from the SRJD calibration vs. market quotes as well as pricing errors (bars) on 31. April 2014 (five maturities)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Calibration without Penalties"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It might be surprising that the highest average MSE value is observed for the calibration case with one maturity only. This is mainly due to the fact that we penalize deviations from previous optimal parameter values quite heavily and the existence of one outlier. The advantage of doing that are rather smooth time series for the single parameters, i.e. without too much variation. This usually is desirable, for example, when such a model is used for hedging purposes and hedge positions (indirectly) depend on the parameter values."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this sub-section we therefore want to illustrate what changes when we do not penalize deviations from the previous optimal parameter values. The following figure shows the results for the model parameters and the MSE values from a calibration to one maturity (18. April 2014) without penalization. Inspection of the figure reveals how erratic the parameter time series can behave in this case."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_1_.png\" width=\"75%\">   \n",
    "   \n",
    "<p style=\"font-family: monospace;\">Square-root jump diffusion parameters and MSE values from the calibration to one maturity without penalization."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, the advantage here are excellent model fits to the market data with a mean MSE value of 0.0007 only (see the following figure)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/dx_srjd_cali_1_hist_.png\" width=\"75%\">   \n",
    "   \n",
    "<p style=\"font-family: monospace;\">Histogram of MSE values for SRJD calibration to one maturity without penalization."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conclusions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This chapter calibrates the square-root jump diffusion (SRJD) model to both the VSTOXX futures term structure and for multiple maturities for the VSTOXX options. It uses DX Analytics like in the previous chapter which provides flexible modeling capabilities for volatility-based derivatives based on, among others, square-root diffusions and square-root jump diffusions.\n",
    "\n",
    "The results we achieve are quite good in that the typical mean-squared error values are relatively low for all cases covered &mdash; and this over the complete three month period we are updating the calibration with only a few outliers. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Python Scripts"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `dx_srjd_calibration.py`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!cat scripts/dx_srjd_calibration.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"http://hilpisch.com/tpq_logo.png\" alt=\"The Python Quants\" width=\"35%\" align=\"right\" border=\"0\"><br>\n",
    "\n",
    "<a href=\"http://tpq.io\" target=\"_blank\">http://tpq.io</a> | <a href=\"http://twitter.com/dyjh\" target=\"_blank\">@dyjh</a> | <a href=\"mailto:team@tpq.io\">team@tpq.io</a>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
